package com.lechi.web.controller;

import com.lechi.iot.netty.utils.NettyCacheUtils;
import com.lechi.web.common.annotation.Log;
import com.lechi.web.common.core.controller.BaseController;
import com.lechi.web.common.core.domain.AjaxResult;
import com.lechi.web.common.core.page.TableDataInfo;
import com.lechi.web.common.enums.BusinessType;
import com.lechi.web.common.enums.ErrorCodeEnum;
import com.lechi.web.common.exception.ServiceException;
import com.lechi.web.common.utils.SecurityUtils;
import com.lechi.web.constants.Constants;
import com.lechi.web.server.AppServer;
import com.lechi.web.server.TcpServer;
import com.lechi.web.service.IIotGatewayService;
import com.lechi.web.system.domain.IotGatewayBo;
import com.lechi.web.util.PortChecker;
import com.lechi.web.vo.IotGatewayUpdateVo;
import com.lechi.web.vo.IotGatewayVo;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 网关类型Controller
 *
 * @author yangguang
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/iot/gateway")
@RequiredArgsConstructor
public class IotGatewayController extends BaseController {

    private final IIotGatewayService iotGatewayService;

    /**
     * 打开tcp 或者数据字典服务端口
     *
     * @param name the name
     * @return Result<T>  ajax result
     */
    @GetMapping("/start/{name}")
    //    @PreAuthorize("@ss.hasPermi('iot:gateway:query')")
    @Log(title = "网关开启", businessType = BusinessType.UPDATE)
    public AjaxResult start(@PathVariable("name") String name) {
        IotGatewayBo iotDevice = iotGatewayService.selectIotGatewayById(name);
        if (iotDevice == null || Constants.SOCKT_OPEN_STATUE.equals(iotDevice.getStatus())) {
            throw new ServiceException("操作失败!");
        }
        iotGatewayService.start(iotDevice);
        IotGatewayBo iotGatewayBo = new IotGatewayBo();
        iotGatewayBo.setId(iotDevice.getId());
        iotGatewayBo.setStatus(Constants.SOCKT_OPEN_STATUE);
        String username = SecurityUtils.getUsername();
        iotGatewayBo.setUpdateBy(username);
        iotGatewayService.updateIotGateway(iotGatewayBo);

        return AjaxResult.success();
    }

    /**
     * 关闭tcp 或者数据字典服务端口
     *
     * @param name the name
     * @return Result<T>  ajax result
     */
    @GetMapping("/stop/{name}")
    @Log(title = "网关关闭", businessType = BusinessType.UPDATE)
    //    @PreAuthorize("@ss.hasPermi('iot:gateway:query')")
    public AjaxResult stop(@PathVariable("name") String name) {
        IotGatewayBo iotDevice = iotGatewayService.selectIotGatewayById(name);
        if (iotDevice == null || Constants.CLOSE_STATUE.equals(iotDevice.getStatus())) {
            throw new ServiceException(ErrorCodeEnum.STOP_ERROR.getValue(), ErrorCodeEnum.STOP_ERROR.getKey());
        }

        if (Constants.MODBUS_RTU.equals(iotDevice.getGatewayName())) {
            TcpServer tcpServer = NettyCacheUtils.get(iotDevice.getGatewayName(), TcpServer.class);
            if (tcpServer == null) {
                throw new ServiceException(ErrorCodeEnum.SERVICE_NOT_EXITS_ERROR.getValue(), ErrorCodeEnum.SERVICE_NOT_EXITS_ERROR.getKey());
            }
            log.error("服务端MODBUS Socket服务停用 : {} ：", iotDevice.getGatewayName());
            tcpServer.stop();
        }

        if (Constants.ANDROID_TCP.equals(iotDevice.getGatewayName())) {
            AppServer tcpServer = NettyCacheUtils.get(iotDevice.getGatewayName(), AppServer.class);
            if (tcpServer == null) {
                throw new ServiceException(ErrorCodeEnum.SERVICE_NOT_EXITS_ERROR.getValue(), ErrorCodeEnum.SERVICE_NOT_EXITS_ERROR.getKey());
            }
            log.error("APP服务端 Socket服务停用 : {} ：", iotDevice.getGatewayName());
            tcpServer.stop();
        }

        IotGatewayBo iotGatewayBo = new IotGatewayBo();
        iotGatewayBo.setId(iotDevice.getId());
        iotGatewayBo.setStatus(Constants.CLOSE_STATUE);
        iotGatewayService.updateIotGateway(iotGatewayBo);

        return AjaxResult.success();
    }


    /**
     * 查询网关类型列表
     *
     * @param iotGatewayVo the iot gateway vo
     * @return the table data info
     */
    @GetMapping("/list")
    //    @PreAuthorize("@ss.hasPermi('iot:gateway:query')")
    public TableDataInfo list(IotGatewayVo iotGatewayVo) {
        startPage();
        IotGatewayBo iotDevice = new IotGatewayBo();
        BeanUtils.copyProperties(iotGatewayVo, iotDevice);
        List<IotGatewayBo> retList = iotGatewayService.selectIotGatewayList(iotDevice);
        return getDataTable(retList);
    }


    /**
     * 新增网关类型
     *
     * @param iotGatewayVo the iot gateway vo
     * @return the ajax result
     */
    @PostMapping("/add")
    @Log(title = "新增网关", businessType = BusinessType.UPDATE)
    //    @PreAuthorize("@ss.hasPermi('iot:gateway:add')")
    public AjaxResult add(@RequestBody @Valid IotGatewayVo iotGatewayVo) {
        if (PortChecker.isPortInUse(iotGatewayVo.getPort().intValue())) {
            return AjaxResult.fail();
        }

        IotGatewayBo iotGatewayBo = new IotGatewayBo();
        BeanUtils.copyProperties(iotGatewayVo, iotGatewayBo);
        // 获取当前的用户名称
        String username = SecurityUtils.getUsername();
        iotGatewayBo.setCreateBy(username);
        iotGatewayService.insertIotGateway(iotGatewayBo);
        return AjaxResult.success();
    }

    /**
     * 修改网关类型
     *
     * @param iotGatewayVo the iot gateway vo
     * @return the ajax result
     */
    @PostMapping("/edit")
    @Log(title = "编辑网关", businessType = BusinessType.UPDATE)
    //    @PreAuthorize("@ss.hasPermi('iot:gateway:edit')")
    public AjaxResult edit(@RequestBody @Valid IotGatewayUpdateVo iotGatewayVo) {
        IotGatewayBo iotGatewayBo = new IotGatewayBo();
        BeanUtils.copyProperties(iotGatewayVo, iotGatewayBo);
        // 获取当前的用户名称
        String username = SecurityUtils.getUsername();
        iotGatewayBo.setUpdateBy(username);
        iotGatewayService.updateIotGateway(iotGatewayBo);
        return AjaxResult.success();
    }
}
